package gameObject;

import gameObject.effect.BulletEffect;
import gameObject.item.ItemArm;
import gameObject.item.ItemSuit;

import javax.microedition.lcdui.game.LayerManager;

import main.Res;

import base.RotatableObject;

public abstract class Unit extends RotatableObject {
	//protected int maxHP;
	protected int hp;
	public int attack;
	public int defend;
	public int speed = 30;
	public int range;
	protected ItemArm arm;
	protected ItemSuit suit;
	private int id;
	protected int targetX=-1;
	protected int targetY=-1;

	protected Unit(int id,int attack,int defend,int speed,int range) {
		// TODO Auto-generated constructor stub
		this.setId(id);
		//this.maxHP = maxHp;
		this.hp = defend;
		this.attack = attack;
		this.defend = defend;
		this.speed = speed;
		this.range = range;
		sprite = Res.createCharacterSprite(id);
	}
	
	protected Unit(int id) {
		this.setId(id);
	}
	public void init(){
		this.hp = getDefend();
	}
	public double getHp()
	{
		return (double)hp*100/getDefend();
	}
	public void incHp(int i)
	{
		hp+=i;
		if(hp>getDefend()){
			hp=getDefend();
		}
	}
	public int getID() {
		return getId();
	}

	public void setArm(ItemArm arm) {
		this.arm = arm;
		if(arm != null){
			this.arm.setOwner(this);
		}
	}

	public void setSuit(ItemSuit suit) {
		this.suit = suit;
		if(suit != null){
			this.suit.setOwner(this);
		}
	}

	public ItemArm getArm() {
		return arm;
	}
	
	public boolean hasArm(){
		return arm != null;
	}
	
	public BulletEffect getCurrentEffect(){
		if(arm == null){
			return null;
		}
		return arm.getCurrentEffect();
	}

	public int getAttackRange(){
		if(arm == null){
			return -1;
		}
		return arm.getRange();
	}
	public int getViewRange(){
		int r = range;
		if(suit != null){
			r += suit.bootRange;
		}
		return r;
	}
	public int getAttack(){
		int a = attack;
		if(suit != null){
			a += suit.bootAttack;
		}
		return a;
	}
	public int getDefend(){
		int d = defend;
		if(suit != null){
			d += defend*suit.armor/100;
		}
		return d;
	}
	public double getSpeed(){
		double sp = (double) speed;
		if(suit != null){
			sp += suit.bootSpeed;
		}
		return sp / 10;
	}
	public ItemSuit getSuit() {
		return suit;
	}
	protected void updatePositon()
	{
		if(arm != null)
		{
			arm.updatePosition();
		}
		if(suit != null)
		{
			suit.updatePosition();
		}
	}
	public void attack(int x,int y) {
		if (arm == null || arm.isActived()) {
			return;
		}
		int dx = x-getX();
		int dy = y-getY();
		setRotation(arc(dx, dy));
		arm.attack(x,y);
	}

	public void update() {
		if (arm != null) {
			arm.update();
		}
		if (suit != null) {
			suit.update();
		}
	}
	public void setTarget(int x,int y){
		targetX = x;
		targetY = y;
	}
	public void deleteTarget(){
		targetX = -1;
		targetY = -1;
	}
	public boolean moveToTarget(){
		if(targetX==-1){
			return true;
		}
		return moveTo(targetX, targetY);
		
	}
	public boolean moveTo(int x, int y) {
		
		return moveTo(x, y, getSpeed());
	}
	public boolean moveTo(int x, int y,double sp) {
		if(arm != null && arm.isActived()){
			return false;
		}
		double dx = x-getX();
		double dy = y-getY();
		
		double d = dist(x, y);
		if(d<sp){
			setPosition(x, y);
			return true;
		}
		else{
			setRotation(arc((int)dx, (int)dy));
			move((int)(dx*sp/d), (int)(dy*sp/d));
			return d<2*sp;
		}
	}

	public void addTo(LayerManager layer) {
		super.addTo(layer);
		if (arm != null) {
			arm.addTo(layer);
		}
		if (suit != null) {
			suit.addTo(layer);
		}
	}

	public void removeFrom(LayerManager layer) {
		super.removeFrom(layer);
		if (arm != null) {
			arm.removeFrom(layer);
		}
		if (suit != null) {
			suit.removeFrom(layer);
		}
	}
	public String getInfoString(){
		return "$(2) "+ String.valueOf(attack)+
				"\n$(3) "+ String.valueOf(defend)+
				"\n$(4) "+ String.valueOf(speed)+
				"\n$(5) "+ String.valueOf(range);
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}
}
